<!-- 
 * 公共table组件
 * @author: 
 * @since: 2022-04-08
 * index.vue
-->
<template>
    <div class="table-container">
        <div class="all-btn">
            <div class="handle-btn">
                <slot></slot>
            </div>
            <div class="com-table-handle" v-if="isShowTableBtn">
                <el-button @click="refreshTable" size="mini">
                    <svg-icon name="shuaxin" class="icon" size="12px"></svg-icon>
                    <span calss="refresh-text">刷新</span>
                </el-button>
                <el-popover placement="bottom" trigger="click" @show="clickFiltersBtn(true)" @hide="clickFiltersBtn(false)">
                    <el-checkbox-group v-model="state.colCheckBoxList">
                        <template v-for="(item, i) in state.colHeader" :key="i">
                            <el-checkbox style="display: bolck" :label="item.prop" @change="filterCol('filter', item.prop, i, $event)" checked>{{ item.label }}</el-checkbox>
                        </template>
                    </el-checkbox-group>
                    <template #reference>
                        <el-button size="mini">
                            <svg-icon name="shaixuan"></svg-icon>
                            <span class="colFiltersText">列筛选</span>
                            <svg-icon :name="isArrows ? 'top-s' : 'below-s'" class="colFiltersIcon"></svg-icon>
                        </el-button>
                    </template>
                    <el-button size="mini" type="text" @click="filterCol('allchecked')">全选</el-button>
                    <el-button size="mini" type="text" @click="filterCol('cancel')">取消全选</el-button>
                </el-popover>
            </div>
        </div>
        <el-table :data="tableData" border style="width: 100%" :header-cell-style="state.headerStyle" fit @selection-change="handleCurrentSelect" class="table" v-loading="loading" ref="comTable">
            <el-table-column v-if="isShowCheckbox" type="selection" width="40" align="center"></el-table-column>
            <el-table-column label="序号" width="50" type="index" v-if="isShowIndex" align="center"></el-table-column>
            <el-table-column v-for="(item, index) in tableHeader" :key="index" :label="item.label" :prop="item.prop" align="center" :width="item.width ? item.width : 'auto'">
                <template #default="scope">
                    <el-input v-if="item.isInput" v-model="scope.row[item.prop]" :placeholder="item.placeholder" :disabled="scope.row[item.isDisabled]" />
                    <div v-if="item.isArray">
                        <div v-for="(val, i) in scope.row[item.prop]" :key="i">
                            <span @click="emitArrayCom(val, item.type)" class="arraySpan">{{ val.title }}</span>
                        </div>
                    </div>
                    <el-tooltip class="box-item" effect="dark" :content="scope.row[item.prop]" placement="top-start" v-if="scope.row['isShowLink']">
                        <span :data-linkNum="`${scope.$index}`" v-if="item.isLink" ref="linkText" class="link-btn-wrap hide" @click="item.function ? emitCom(item.function, scope.row) : ''">{{ scope.row[item.prop] }}</span>
                    </el-tooltip>
                    <div v-if="!scope.row['isShowLink']">
                        <span :data-linkNum="`${scope.$index}`" v-if="item.isLink" ref="linkText" class="link-btn-wrap" @click="item.function ? emitCom(item.function, scope.row) : ''">{{ scope.row[item.prop] }}</span>
                    </div>
                    <span v-if="item.status">{{ scope.row[item.prop] ? '启用' : '禁用' }}</span>
                    <span v-if="item.yesOrNo">{{ scope.row[item.prop] ? '是' : '否' }}</span>
                    <div class="imgCol" v-if="item.isImg">
                        <el-image style="width: 40px; height: 40px" :src="scope.row[item.prop] ? scope.row[item.prop] : defaultLogo" @click.capture="previewEvent($event, scope.row, scope.$index)"></el-image>
                    </div>
                    <el-tooltip class="box-item" effect="dark" :content="scope.row[item.prop]" placement="top-start" v-if="scope.row[item.isShowTooltip]">
                        <span v-if="!item.isInput && !item.isLink && !item.status && !item.isImg" ref="textDom" class="textDom hide" :data-num="`${index}/${scope.$index}`">{{ scope.row[item.prop] }}</span>
                    </el-tooltip>
                    <div v-if="!scope.row[item.isShowTooltip]">
                        <span class="textDom" v-if="!item.isInput && !item.isLink && !item.status && !item.isImg && !item.isArray && !item.yesOrNo" ref="textDom" :data-num="`${index}/${scope.$index}`">{{ scope.row[item.prop] }}</span>
                    </div>
                </template>
            </el-table-column>
            <el-table-column label="操作" v-if="isShowGrooveHandleCol" align="center" :width="handleWidth" fixed="right">
                <template v-slot="scope">
                    <div v-if="btnData.length" class="btnData" style="margin: 0 auto;">
                        <div v-for="(item, index) in btnData" :key="index" class="btn-item">
                            <div v-if="item.isStart" class="singleBtn">
                                <span class="first">{{ item.name }}</span>
                                <el-switch v-model="scope.row[item.prop]" @change="item.change ? emitCom(item.change, scope.row) : ''" class="switch" />
                            </div>
                            <div v-else class="singleBtn"  @click="item.change ? emitCom(item.change, scope.row) : ''">
                                <span :style="{ color: item.color }">{{ item.name }}</span>
                            </div>
                        </div>
                    </div>
                    <div class="interval" v-if="btnData.length && isShowByStatus"></div>
                    <div v-if="isShowByStatus" @click="statusHandle(scope.row)" class="statusBtn">
                        <span :style="{ color: props.handleFun(scope.row.status).color }">{{ props.handleFun(scope.row.status).text }}</span>
                    </div>
                </template>
            </el-table-column>
            <el-table-column label="操作" v-if="isShowLogicHandleCol" align="center" :width="handleWidth" fixed="right">
                <template #default="scope">
                    <slot name="handle" :row="scope.row"></slot>
                </template>
            </el-table-column>
        </el-table>
        <div class="pagination-box" v-if="showPage">
            <el-pagination background :currentPage="pagination.currentPage" :page-size="pagination.size" :total="pagination.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pagination.currentPage" layout="total,sizes,prev, pager, next,jumper" :page-sizes="[10, 20, 30, 40]"></el-pagination>
        </div>
    </div>
    <!-- 图片查看器 -->
    <el-image-viewer v-if="state.isShowViewer" @close="() => (state.isShowViewer = false)" :url-list="previewImgList" />
</template>

<script setup>
import defaultLogo from '@/assets/img/defaultLogo.png'
import { defineProps, defineEmits, reactive, ref, onMounted, defineExpose, computed, nextTick, onBeforeUpdate, inject } from 'vue'
const reload = inject('reload')

const props = defineProps({
    tableData: {//table数据
        type: Array,
        default: () => [],
        required: true,
    },
    isShowCheckbox: {//是否展示复选框
        type: Boolean,
        require: false,
        default: true,
    },
    tableHeader: { //table的header名称
        type: Array,
        required: true,
    },
    btnData: { //存放单行操作按钮信息
        type: Array,
        default: () => [],
    },
    showPage: { //是否显示分页插件
        type: Boolean,
        require: false,
        default: true,
    },
    pagination: { //分页  currentPage:当前页 size：获取的条数 total：列表的总条数
        type: Object,
    },
    handleWidth: {//操作栏的宽
        type: String,
        default: 'auto',
    },
    isShowIndex: {//是否显示序号
        type: Boolean,
        default: true,
    },
    loading: {//区域加载
        type: Boolean,
        default: true,
    },
    isShowTableBtn: {//是否展示表格功能按钮
        type: Boolean,
        default: true,
    },
    roleId: {//角色id
        type: [Number, String]
    },
    handleFun: {//操作函数----根据状态码决定表格操作按钮
        type: Function,
    },
    isShowGrooveHandleCol: {//是否显示常规操作列
        type: Boolean,
        default: true
    },
    isShowLogicHandleCol: {//是否显示根据逻辑判断的操作列
        type: Boolean,
        default: false
    },
    isShowByStatus: {//是否显示根据状态码决定表格操作按钮
        type: Boolean,
        default: false
    },
})


//table dom实例 
const comTable = ref()

//linkText dom实例
const linkText = ref()
//text dom实例
const textDom = ref()



//数据
const state = reactive({
    headerStyle: { 'background-color': '#F6F9FB' },
    comEvent: '',
    colHeader: [],
    colCheckLabels: [], // 表格筛选列显示多选框数据
    colCheckBoxList: [], // 表格筛选列的数据
    currentImgIndex: null,//当前图片的index
    isShowViewer: false

})
//表格预览图片列表
const previewImgList = ref([])

//列筛选箭头
const isArrows = ref(false)

onBeforeUpdate(() => {
    tableWord()
    window.onresize = () => {
        return (() => {
            tableWord()
            reload()
        })()
    }
})
onMounted(() => {
    state.colHeader = ref(props.tableHeader).value
    tableWord()
    window.onresize = () => {
        return (() => {
            tableWord()
            reload()
        })()
    }
})

const tableWord = () => {
    nextTick(() => {
        let els = linkText.value;
        let textEls = textDom.value
        if (els) {
            els.forEach(item => {
                const linkNum = Number(item.dataset.linknum);
                if (item.scrollHeight > 41) {
                    props.tableData[linkNum]['isShowLink'] = true
                }
            })
        }
        if (textEls) {
            textEls.forEach((item) => {
                const newsString = item.dataset.num.split('/')
                if (item.scrollHeight > 41) {
                    const key = `is${props.tableHeader[newsString[0]].prop}`
                    props.tableHeader[newsString[0]].isShowTooltip = key
                    props.tableData[newsString[1]][`${key}`] = true
                }
            })

        }
    })

}


//表格中图片预览
const previewEvent = (e, data, index) => {
    e.stopPropagation();
    state.isShowViewer = true
    props.tableData.forEach(item => {
        if (!item.logoUrl) {
            item.logoUrl = defaultLogo
        }
    })
    previewImgList.value = props.tableData.map(item => item.logoUrl)
    let tempImgList = [...previewImgList.value];
    let currentImgList = tempImgList.filter(item => item === data.logoUrl)
    tempImgList = tempImgList.filter(item => item !== data.logoUrl)
    previewImgList.value = [...currentImgList, ...tempImgList]
}


//回显后端选中的值 -- 角色用
const returnSelect = () => {
    comTable.value.clearSelection();
    props.tableData.forEach(item => {
        if (item.hasOwnProperty('userRoleId')) {
            item.userRoleId.forEach(val => {
                if (val === props.roleId) {
                    comTable.value.toggleRowSelection(item, true)
                }
            })
        }
    })
}

//回显后端选中的值 -- 项目添加人员用
const returnSelectProjects = (list) => {
    comTable.value.clearSelection();
    props.tableData.forEach(item => {
        if (list) {
            list.forEach(val => {
                if (val === item.userName) {
                    comTable.value.toggleRowSelection(item, true)
                }
            })
        }
    })
}

const emit = defineEmits(['getSelectChange', 'comEvent', 'event', 'getCurrentChange', 'colSelect', 'refresh', 'getSizeChange', 'statusHandleEvent', 'emitArrayCom'])

//根据状态点击事件
const statusHandle = (row) => {
    emit('statusHandleEvent', row)

}

//选中当前行
const handleCurrentSelect = (row) => {
    emit('getSelectChange', row)
}
//公共emit
const emitCom = (event, data) => {
    console.log(data, '--表格组件--')
    emit('comEvent', event, data)
}

//数组中的emit
const emitArrayCom = (data, type) => {
    emit('emitArrayEvent', data, type)
}

//点击当前条数
const handleSizeChange = (val) => {
    emit('getSizeChange', val)
}
//点击当前页
const handleCurrentChange = (val) => {
    emit('getCurrentChange', val)
}

// 列筛选
const filterCol = (type, currentItem, index, e) => {
    switch (type) {
        case 'filter':
            if (e === false) {
                //取消
                emit('colSelect', ref(props.tableHeader).value, type, e, currentItem)
            } else {
                //选中
                emit('colSelect', state.colHeader, type, e, currentItem)
            }
            break
        case 'allchecked':
            state.colHeader.forEach((item) => {
                state.colCheckLabels.push(item.prop)
            })
            state.colCheckBoxList = state.colCheckLabels
            emit('colSelect', state.colHeader) // 复选框置为复选所有值，全部选择
            break
        case 'cancel':
            state.colCheckBoxList = [] // 复选框置为空，全部不选择
            emit('colSelect', [])
            break
    }
}

//点击列筛选按钮
const clickFiltersBtn = () => {
    isArrows.value = !isArrows.value
}

//刷新table事件
const refreshTable = () => {
    emit('refresh')
}
//回显已经选中的值
const getRowSelectKeys = (row) => {
    //   emit('rowSelectKeys', row)
}
defineExpose({
    returnSelect,
    returnSelectProjects

})
</script>


<style lang="scss" scoped>
.table-container {
    padding: 10px 20px;

    :deep(.el-table-column--selection) {
        .cell {
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
        }
    }

    .hide {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .link-btn-wrap {
        width: 100%;
        display: block;
        color: #00a2ff !important;
        cursor: pointer;
    }

    .textDom {
        width: 100%;
        display: block;
    }

    :deep(.el-switch__core) {
        width: 26px !important;
        height: 13px;
        margin-top: -2px;
    }

    :deep(.el-switch.is-checked .el-switch__core::after) {
        margin-left: 10px;
    }

    :deep(.el-switch__action) {
        width: 11px;
        height: 11px;
        margin-top: -1px;
    }

    :deep(.el-switch.is-checked .el-switch__core .el-switch__action) {
        left: 100%;
        margin-left: calc(-1px - 9px);
    }

    .all-btn {
        display: flex;

        .handle-btn {
            flex: 1;
        }

        .com-table-handle {
            display: flex;
            justify-content: flex-end;

            .icon {
                margin-right: 5px;
            }

            .colFiltersText {
                margin: 0 20px 0 5px;
            }
        }
    }

    .col-Filters {
        display: flex;
        justify-content: flex-end;
    }

    .table {
        margin: 10px 0;

        :deep(.cell) {
            font-size: $base-font-size-small;
        }
    }

    :deep(.el-table-fixed-column--right) {
        .cell {
            display: flex;

            .btnData {
                display: flex !important;
                align-items: center;

                div {
                    cursor: pointer;
                }

                .btn-item {
                    margin-right: 10px;

                    &:last-child {
                        margin-right: 0;
                    }
                }
            }

            .statusBtn {
                cursor: pointer;
                margin-right: 10px;
                display: flex;

                &:last-child {
                    margin-right: 0;
                }
            }
        }

        .singleBtn {
            width: 100%;
            display: flex;
            align-items: center;
        }
    }

    .pagination-box {
        width: 100%;
        display: flex;
        justify-content: center;
        margin-top: 20px;
    }

    .imgCol {
        display: flex;
        align-items: center;
        justify-content: center;

        .el-image {
            border: 1px solid #e3e3e3;
            border-radius: 4px;
            cursor: pointer;
            line-height: 38px;
        }
    }

    .interval {
        margin-right: 10px;
    }

    .arraySpan {
        display: block;
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        cursor: pointer;
        color: #00a2ff !important;
    }
}
</style>